package com.haidung.photojourney.activities.based;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.haidung.photojourney.PhotoJourneyApplication;
import com.haidung.photojourney.R;
import com.haidung.photojourney.utils.LocationUtil;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.widget.Toast;

public class LocationBasedActivity extends SherlockFragmentActivity implements
		LocationListener, GooglePlayServicesClient.ConnectionCallbacks,
		GooglePlayServicesClient.OnConnectionFailedListener {
	private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST_CODE = 9000;
	
	protected PhotoJourneyApplication app;
	protected LocationClient locationClient;
	protected LocationRequest locationRequest;
	protected boolean noStopLocationClientOnStop = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		app = (PhotoJourneyApplication) getApplication();
		locationClient = new LocationClient(this, this, this);
		
		 // Create a new global location parameters object
		locationRequest = LocationRequest.create();
        // Use high accuracy
		locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
         // Set the update interval
		locationRequest.setInterval(LocationUtil.UPDATE_INTERVAL);
        // Set the interval ceiling to one minute
		locationRequest.setFastestInterval(LocationUtil.FAST_INTERVAL_CEILING);
		
		super.onCreate(savedInstanceState);
	}
	
	@Override
	public void onStop() {
		if (this.noStopLocationClientOnStop) {
			this.noStopLocationClientOnStop = false;
		} else {
			stopLocationClient();
		}
		
		super.onStop();
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		if (requestCode == CONNECTION_FAILURE_RESOLUTION_REQUEST_CODE) {
			if (resultCode == Activity.RESULT_OK) {
				app.showLongTimeToast(getString(R.string.play_service_resolved));
			} else {
				app.showLongTimeToast(getString(R.string.play_service_no_resolution));
			}
		}
	}
	
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(this, 
                		CONNECTION_FAILURE_RESOLUTION_REQUEST_CODE);
            } catch (IntentSender.SendIntentException e) {
                Toast.makeText(this, "Error: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
            }
        } else {
            // If no resolution is available, display a dialog to the user with the error.
            showErrorDialog(connectionResult.getErrorCode());
        }
    }
    
    private void showErrorDialog(int errorCode) {
        // Get the error dialog from Google Play services
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
            errorCode, this, CONNECTION_FAILURE_RESOLUTION_REQUEST_CODE);

        // If Google Play services can provide an error dialog
        if (errorDialog != null) {
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();
            errorFragment.setDialog(errorDialog);
            errorFragment.show(getSupportFragmentManager(), LocationBasedActivity.class.getName());
        }
    }
    
    public static class ErrorDialogFragment extends DialogFragment {
        private Dialog dialog;

        public ErrorDialogFragment() {
            super();
            this.dialog = null;
        }

        public void setDialog(Dialog dialog) {
        	this.dialog = dialog;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return dialog;
        }
    }
    
    @Override
	public void onLocationChanged(Location location) {
		
	}

	@Override
	public void onConnected(Bundle connectionHint) {
		if (isServiceAvailable()) {
        	locationClient.requestLocationUpdates(locationRequest, this);
        }
	}
	
	/**
     * Verify that Google Play services is available before making a request.
     * @return true if Google Play services is available, otherwise false
     */
    private boolean isServiceAvailable() {
        // Check that Google Play services is available
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        // If Google Play services is available
        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        // Google Play services was not available for some reason
        } else {
            showErrorDialog(resultCode);
            return false;
        }
    }

	@Override
	public void onDisconnected() {
		
	}
	
	protected void stopLocationClient() {
        if (locationClient.isConnected() && isServiceAvailable()) {
        	locationClient.removeLocationUpdates(this);
        }
        locationClient.disconnect();
    }
	
	protected void prepareLocationClient() {
		locationClient.connect();
		this.noStopLocationClientOnStop = true;
	}
	
	protected Location getLastLocation() {
		if (locationClient.isConnected()) {
			return locationClient.getLastLocation();
		} else {
			return null;
		}
	}
}
